package com.grandtech.insurance.common.utils.trans;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.grandtech.insurance.common.db.jdbc.sql.ReflectUtil;
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * Created by zy on 2016/11/23.
 * Map<K-V>工具类
 */

public class MapUtil {

    private MapUtil() {
    }

    /**
     * 合并两个Map
     *
     * @return
     */
    public static Map<String, Object> merge2Map(Map<String, Object> map1, Map<String, Object> map2) {
        Map<String, Object> map = new HashMap<>();
        map.putAll(map1);
        map.putAll(map2);
        return map;
    }

    /**
     * Map的拆分
     *
     * @param map
     * @param s
     * @return
     */
    public List<Map<String, Object>> splitMap(Map<String, Object> map, String[] s) {
        List<Map<String, Object>> list = null;
        int flag = 0;
        for (int i = 0; i <= s.length; i++) {
            Map<String, Object> temp = new HashMap<>();
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                temp.put(entry.getKey(), entry.getValue());
                flag++;
                if (entry.getKey().equals(s[i])) {
                    break;
                }

            }
            list.add(temp);
        }
        return null;
    }

    private static Gson gson;

    public static Map<String, String> entity2Map(String key, Object obj) {
        if (gson == null) {
            gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        }
        String value = gson.toJson(obj);
        Map<String, String> map = new HashMap<>();
        map.put(key, value);
        return map;
    }

    public static String entity2Json(Object obj) {
        if (gson == null) {
            gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        }
        String value = gson.toJson(obj);
        return value;
    }

    public static <T> T string2Entity(String json, Class clazz) {
        if (gson == null) {
            gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        }
        T t = (T) gson.fromJson(json, clazz);
        return t;
    }


    public static Map<String, Object> str2MapRes(String json) {
        Map<String, Object> res = null;
        JSONObject jsonObject;
        try {
            res = new HashMap<>();
            jsonObject = new JSONObject(json);
            Integer code = jsonObject.getInt("code");
            res.put("code", code);
            String msg = jsonObject.getString("msg");
            res.put("msg", msg);
            if (jsonObject.isNull("data")) {
                res.put("data", null);
            } else {
                Object data = jsonObject.get("data");
                res.put("data", data.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    public static Map<String, Object> str2MapRes(Object json) {
        Map<String, Object> res = null;
        JSONObject jsonObject;
        try {
            res = new HashMap<>();
            jsonObject = new JSONObject(json.toString());
            Integer code = jsonObject.getInt("code");
            res.put("code", code);
            String msg = jsonObject.getString("msg");
            res.put("msg", msg);
            if (jsonObject.isNull("data")) {
                res.put("data", null);
            } else {
                Object data = jsonObject.get("data");
                res.put("data", data.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }


    /**
     * JSON转成list集合
     *
     * @param
     * @param cls
     * @return
     */
    public static <T> List<T> GsonToList(String gsonStr, Class<T> cls) {
        if (gson == null) {
            gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        }
        List<T> list = gson.fromJson(gsonStr, new TypeToken<List<T>>() {
        }.getType());
        return list;
    }

    /**
     * Map转成实体对象
     *
     * @param map   map实体对象包含属性
     * @param clazz 实体对象类型
     * @return
     */
    public static <T> T map2Entity(Map<String, Object> map, Class<?> clazz) {
        if (map == null) {
            return null;
        }
        Object obj = null;
        try {
            obj = clazz.newInstance();
            Field[] fields = obj.getClass().getDeclaredFields();
            String columnName;
            for (Field field : fields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                columnName = ReflectUtil.getColumnName(field);
                field.set(obj, map.get(columnName));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) obj;
    }


    public static Map json2Map(String json) {
        try {
            JSONObject jsonObject = new JSONObject(json);
            Map<String, Object> map = new HashMap<>();
            Iterator it = jsonObject.keys();
            while (it.hasNext()) {
                String key = (String) it.next();
                Object value = jsonObject.get(key);
                map.put(key, value);
            }
            return map;
        } catch (Exception e) {
            return null;
        }
    }

    public static SimpleMap entityField2Map(Object o, String... fieldNames) {
        SimpleMap<String, Object> condition = new SimpleMap<>();
        if (fieldNames == null && fieldNames.length == 0) return null;
        for (int i = 0; i < fieldNames.length; i++) {
            condition.put(fieldNames[i], ReflectUtil.getValByNumberVar(o, fieldNames[i]));
        }
        return condition;
    }

    public static Map sortMapKey(Map<String, Object> map) {
        if (map == null) return null;
        Map<String, Object> res = new LinkedHashMap<>();
        List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(map.entrySet());
        //排序方法
        Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
            public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                return (o1.getKey()).toString().compareTo(o2.getKey());
            }
        });
        //排序后
        for (Map.Entry<String, Object> m : infoIds) {
            res.put(m.getKey(), m.getValue());
        }
        return res;
    }
}
